package com.errol.sync.sync.wrapper;

import com.renjia.supervise.service.log.LogService;
import com.renjia.supervise.service.sync.DataSyncService;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.time.LocalDate;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 异步执行数据同步的 wrapper
 *
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/08/16
 * @since v
 **/
public class AsyncDataSyncWrapper extends AbsDataSyncWrapper {

    private final ThreadPoolTaskExecutor taskExecutor;

    AsyncDataSyncWrapper(DataSyncService source, TaskExecutor taskExecutor, LogService logService) {
        super(source, logService);
        this.taskExecutor = (ThreadPoolTaskExecutor) taskExecutor;
    }

    /**
     * 使用 @Async 线程池异步执行，get 等待 1秒
     *
     * @param entityClass 实体类型
     * @param callable    同步执行方法
     * @param <E>         实体类型
     * @return 同步完成结果，或提示异步执行中
     */
    private <E> String doAsync(Class<E> entityClass, Callable<String> callable) {
        Future<String> submit = taskExecutor.submit(callable);
        // 等待一秒，超时返回等待中，否则返回结果
        try {
            return submit.get(1000, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            return asyncRunning(entityClass);
        } catch (Exception e) {
            return logService.error(e, "异步执行同步任务异常：" + e.getMessage());
        }
    }

    private String asyncRunning(Class<?> entityClass) {
        return entityClass.getSimpleName() + "同步任务执行中，请关注日志";
    }

    @Override
    public <E> String syncData(Class<E> entityClass, LocalDate rangeLeft, LocalDate rangeRight, boolean updateEditedData) {
        return doAsync(entityClass, () -> source.syncData(entityClass, rangeLeft, rangeRight, updateEditedData));
    }
}
